import java.util.concurrent.locks.ReentrantLock;

public class ThreadReentrantLockTest {
    public static void main(String[] args) {
        // ReentrantLock 测试
        ReentrantLock reentrantLock = new ReentrantLock();
        boolean result = reentrantLock.tryLock();

        try {
          //  reentrantLock.lock();
            // 这中间的进行加锁 (这样的写法并不是最好的选择 , 因为分开写 unlock 就很可能执行不到)
            // 如果 中间有个return unlock就执行不到了
       /* if(count){
            return;
        }*/

            // 或者是 抛出了一个什么异常
            //throw new Exception();
           //  reentrantLock.unlock();

            // 那么解决方法就是 , 在写的时候
            // 务必要把  reentrantLock.unlock(); 写到 finally 里面

           if(reentrantLock.tryLock()) {
           }else{

           }

        }finally {
            reentrantLock.unlock();
        }

        //上面是 ReentrantLock 的劣势 , 但也是有优势的 (与 synchronized 相比)
        // 优势 :
        // 1. ReentrantLock 提供了 公平锁版本的实现
        // new ReentrantLock(true) 在 构造方法里面写 ture 就是公平锁 , 写false或者 不写 就是不公平锁

        // 2. 对于synchronized来说使用 提供的加锁操作 就是 死等, 只要取不到锁 就一直等
        // 而 ReentrantLock 提供了更灵活的等待方式 : tryLock 有两个版本
        // reentrantLock.tryLock();  无参数版本 , 能加上就加,加不上就放弃
        // reentrantLock.tryLock(); 有参数版本,指定了 超时时间, 加不上锁就等待一会. 如果等一会时间到了也没加上 就放弃
        // tryLock 是有返回值的 , 加锁成功了 就返回 true 就可以执行 unlock

        // 3. ReentrantLock 提供了一个更强大 更方便的 等待通知机制.
        // synchronized 搭配的是 wait notify, notify 的时候 是随机唤醒一个wait 的线程
        // ReentrantLock 搭配一个 Condition 类, 进行唤醒的时候可以唤醒指定的线程
        // 但是在工作中还是用 synchronized 的比较多

        // synchronized 和 ReentrantLock 没法针对同一个对象 , synchronized 是针对{}里的对象, 本质上是JVM内部C++实现的代码
        // ReentrantLock 的 锁对象就是你定义的 ReentrantLock 实例 ( ReentrantLock reentrantLock = new ReentrantLock();)
        // 此时都是在 java 代码层面上进行锁对象的控制
        // 这里的可重入的实现方式 应该是非常相似的

    }
}
